/*
 * InodeManager.h
 *
 *  Created on: Mar 28, 2010
 *      Author: Lukasz Spintzyk
 */

#ifndef INODEREADER_H_
#define INODEREADER_H_

#ifndef PH_H_
#include "ph.h"
#endif

#ifndef BLKINDEX2NUMTRANSLATOR_H_
#include "BlkIndex2NumTranslator.h"
#endif


#ifndef INODEBLOCKSADDER_H_
#include "InodeBlocksAdder.h"
#endif

class SuperBlock;
class BlockManager;
class Inode;


class InodeManager {
public:
	typedef std::map<uint32_t, InodePtr > InodeMap;
	typedef InodeMap::const_iterator InodeMap_cit;
	typedef InodeMap::iterator InodeMap_it;

	InodeManager(BlockManager& reader, SuperBlock& sb);
	virtual ~InodeManager();

    InodePtr getInode(uint32_t nb);
    bool setInode(uint32_t nb, const InodePtr inode);


    bool reserveBlocksForInode(InodePtr i, uint32_t num_of_blocks);
    void releaseInodeBlocks(InodePtr inode);


    void decrementLinksCount(InodePtr inode);



    uint32_t blkIndex2BlkNum(InodePtr i, uint32_t block_index);
    uint32_t getBlkNumRange(InodePtr inode, uint32_t startIndex, uint32_t* buffer_block);
    uint32_t getLastUsedBlockNumber(InodePtr inode);
    uint32_t getLastReservedBlockNumber(InodePtr inode);

    SuperBlock& getSuperBlock();


    InodePtr createNewInode();
    void freeInode(uint32_t nb);

protected:
    void addUsedInodesCount(int32_t add);
    uint32_t maxBlocksNumPerInode();


    uint32_t directBlkNum() const;
    uint32_t indirectBlkNum() const;
    uint32_t doubleIndirectBlkNum() const;
    uint32_t tripleIndirectBlkNum() const;

    bool hasInodeSpaceForBlocksNum(InodePtr inode, uint32_t blocks_num);
    uint32_t getLastReservedBlockNumberOrDefault(InodePtr inode);

private:
    byte* d_buffer;
    byte* d_buffer2;
    byte* d_buffer3;
    BlockManager& d_reader;
    SuperBlock& d_sb;
    InodeMap d_inodes;
    BlkIndex2NumTranslator d_blkTranslator;
    InodeBlocksAdder d_blkAdder;
};

#endif /* INODEREADER_H_ */
